<?php


namespace common\drivers;

use Yii;
use common\models\com\ComCookies;
use common\constants\PlatformConst;

class CookieDriver
{
    /**
     * cookie队列key
     * @var string
     */
    protected $cookie_key = '';

    /**
     * cookie队列有效期key
     * @var string
     */
    protected $cookie_expire_key = '';

    /**
     * 队列有效期时间
     * @var float|int
     */
    protected $cookie_expire_time = 300;

    /**
     * @var int
     */
    protected $platform = 0;


    /**
     * CookieDriver constructor.
     * @param int $platform
     */
    public function __construct($platform = PlatformConst::PLATFORM_TB)
    {
        $this->platform = $platform;
        $this->cookie_key = "cache_spider_cookies:" . $platform;
        $this->cookie_expire_key = $this->cookie_key . ":expire_key";

        $this->checkListExpire();
    }

    /**
     * get cookie
     * @return array|mixed
     */
    public function getCookie()
    {
        $len = Yii::$app->redis->llen($this->cookie_key);
        $is_expire = Yii::$app->redis->get($this->cookie_expire_key);
        $now = date("Y-m-d H:i:s");
        $return = [];
        if (!$len || !$is_expire) {//队列为空或者已过有效期，重新从数据表获取
            $models = ComCookies::find()->where(['platform' => $this->platform])->andFilterWhere(['>=', 'id', 100])->orderBy("last_at asc")->limit(100)->all();
            foreach ($models as $k => $model) {
                $model = $model->toArray();
                if ($k == 0) {
                    $return = $model;
                    $model['last_at'] = $now;
                    $model['nums'] += 1;
                }
                Yii::$app->redis->lpush($this->cookie_key, base64_encode(json_encode($model, JSON_UNESCAPED_UNICODE)));
            }
            if ($models) {//设置队列过期时间
                Yii::$app->redis->setex($this->cookie_expire_key, $this->cookie_expire_time, 1);
            }
        } else {
            $base64_cookie = Yii::$app->redis->lpop($this->cookie_key);
            $cookie_arr = json_decode(base64_decode($base64_cookie), true);
            $return = $cookie_arr;
            $cookie_arr['last_at'] = $now;
            $cookie_arr['nums'] += 1;
            //将获取到的cookie放入队列最右端
            Yii::$app->redis->rpush($this->cookie_key, base64_encode(json_encode($cookie_arr, JSON_UNESCAPED_UNICODE)));
        }
        return $return;
    }

    /**
     * cookie使用反馈
     * @param array $cookie
     * @param $is_active
     */
    public function callback(array $cookie)
    {
        $base64_cookie = base64_encode($cookie);
        Yii::$app->redis->lrem($this->cookie_key, 0, $base64_cookie);
        //delete DB
        $cookie_arr = json_decode($base64_cookie, true);
        $id = $cookie_arr['id'] ?? 0;
        if ($id) {
            ComCookies::findOne($id)->delete();
        }
    }

    /**
     * 检查队列是否过期，若过期，更新队列数据到DB
     */
    protected function checkListExpire()
    {
        $is_expire = Yii::$app->redis->get($this->cookie_expire_key);
        $len = Yii::$app->redis->llen($this->cookie_key);
        if ($len && !$is_expire) {//队列已过期
            for ($i = 0; $i < $len; $i++) {
                $base64_cookie = Yii::$app->redis->lpop($this->cookie_key);
                $cookie_arr = json_decode(base64_decode($base64_cookie), true);
                ComCookies::updateAll(['nums' => $cookie_arr['nums'], 'last_at' => $cookie_arr['last_at']], ['id' => $cookie_arr['id']]);
            }
        }
    }
}